/************************************************************************
* map_triggers.c
* voxelands - 3d voxel world sandbox game
* Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>
************************************************************************/

#include "common.h"
#include "array.h"

#include "map.h"

static struct {
	uint8_t isinit;
	array_t callbacks[MAP_TRIGGER_COUNT];
} map_trigger_data = {
	0
};

static int map_trigger_init()
{
	int i;

	for (i=MAP_TRIGGER_MIN; i<MAP_TRIGGER_COUNT; i++) {
		array_init(&map_trigger_data.callbacks[i],ARRAY_TYPE_PTR);
	}

	map_trigger_data.isinit = 1;

	return 0;
}

/* trigger a map event */
int map_trigger(uint32_t type, chunk_t *ch, pos_t *p)
{
	int i;
	array_t *c;
	void (**fn)(chunk_t*,pos_t*);
	if (!map_trigger_data.isinit)
		return 0;

	if (type < MAP_TRIGGER_MIN || type > MAP_TRIGGER_MAX)
		return 1;

	c = &map_trigger_data.callbacks[type];
	fn = c->data;

	/* TODO: these return success/failure, should probably do something with that */
	for (i=0; i<c->length; i++) {
		fn[i](ch,p);
	}

	return 0;
}

/* add a callback to a map event trigger */
int map_trigger_add(uint32_t type, void (*fn)(chunk_t*,pos_t*))
{
	if (!map_trigger_data.isinit)
		map_trigger_init();

	if (type < MAP_TRIGGER_MIN || type > MAP_TRIGGER_MAX)
		return 1;

	array_push_ptr(&map_trigger_data.callbacks[type], *((void**)&fn));

	return 0;
}

/* clear all map event triggers */
void map_trigger_clear()
{
	int i;

	if (!map_trigger_data.isinit)
		return;

	for (i=MAP_TRIGGER_MIN; i<MAP_TRIGGER_COUNT; i++) {
		array_free(&map_trigger_data.callbacks[i],0);
	}
}
